於Arduino端接收MQTT資料字串

完成上一個步驟之後,接下來要對 Serial 1進行測試,確保資料在傳送的過程中不會因為電路的誤差而「糟精」(台語:偏差)的疑慮,這種時候,阿海都會直接打開 Arduino IDE 中的範例 「MultiSrerialMEGA」,這個好用的工具範例,修改兩端到要使用的 Buadrate,隨即測試接收資料看看。

圖1:Arduino IDE 中 MultiserialMEGA

圖2:透過 Serial Console確認資料無誤

當確認傳來的資料是相同的之後,就開始著手撰寫通訊程式,Arduino中,剛好能夠利用String 物件輕鬆的操作字串,而MQTT訊息串並不是太大,於是就將所有的資料流存,放到字串裡面。

得到字串之後,就來設計解析字串程式,這邊要取得的有「日期」、「時間」、「溫度」、「溼度」、「PM2.5」、「PM10」這六項資料。其中前兩項並不是數字,所以撰寫一段額外的程序,來分別放置在字串變數,和浮點數陣列之中。而解析時只要找到tag的前置名稱加上「=」號的開頭位置,以及結尾的「|」符號,就能夠取出這段資料。

首先宣告想要截取的特徵前導字元:

#include <avr/pgmspace.h>
  const char data_datep[] PROGMEM = "date";
  const char data_timep[] PROGMEM = "time";
  const char interestValue_1[] PROGMEM = "s_d0";
  const char interestValue_2[] PROGMEM = "s_t0";
  const char interestValue_3[] PROGMEM = "s_h0";
  const char interestValue_4[] PROGMEM = "s_d1";
  const char* const interestValue[] PROGMEM = {data_datep, data_timep , interestValue_1, interestValue_2, interestValue_3, interestValue_4, };

然後尋找特徵碼的開頭,並使用 String.indexOf 定位,將所需要的部分轉換成數值,存放在浮點數陣列之中。

float sensorValue[4];
char buffer[8];

boolean onMessage(){
  Serial.println("OnMessage");
  for(int i=0;i<=data_num-1;i++){
    strcpy_P(buffer, (char*)pgm_read_word(&(interestValue[i])));
    byte startpos=msg.indexOf(buffer);
    String temp =msg.substring(msg.indexOf(assigner,startpos)+1,msg.indexOf(seperator,startpos)); //From tagname after'=' to seperator'|'
   if(temp==""){
    return 0; //if failed to match tags....
    }
   if(i==0){
    data_date = temp; 
   } else if(i==1){
    data_time = temp;
   } else {
    sensorValue[i-2]=temp.toFloat();
   }
    Serial.println(temp);
  }
  return 1; // I count 2440 message/second with static process , so maybe perfomence is about 100~1000 message/s.
}

將這些資料印在Serial上,確認解析字串成功之後,就要準備來顯示在 128 x 64 的繪圖型 OLED 上了。

圖3:於Serial觀察解析字串的結果